home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / x / volume3 / awm2 / part05 < prev    next >
Encoding:
Internet Message Format  |  1989-02-20  |  54.9 KB

  1. Path: uunet!lll-winken!ames!mailrus!tut.cis.ohio-state.edu!ucbvax!decwrl!wyse!mikew
  2. From: mikew@wyse.wyse.com (Mike Wexler)
  3. Newsgroups: comp.sources.x
  4. Subject: v03i021:  Ardent Window Manager, Patchlevel 9, Part05/12
  5. Message-ID: <2071@wyse.wyse.com>
  6. Date: 20 Feb 89 22:24:15 GMT
  7. Organization: Wyse Technology, San Jose
  8. Lines: 1768
  9. Approved: mikew@wyse.com
  10.  
  11. Submitted-by: kmw@ardent (Ken Wallich)  
  12. Posting-number: Volume 3, Issue 21
  13. Archive-name: awm2/part05
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 5 (of 12)."
  22. # Contents:  Pause.c awm.h menus/track_menu.c
  23. # Wrapped by mikew@wyse on Fri Feb 17 10:50:23 1989
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f 'Pause.c' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'Pause.c'\"
  27. else
  28. echo shar: Extracting \"'Pause.c'\" \(3003 characters\)
  29. sed "s/^X//" >'Pause.c' <<'END_OF_FILE'
  30. X
  31. X
  32. X
  33. X#ifndef lint
  34. Xstatic char *rcsid_Pause_c = "$Header: /usr/graph2/X11.3/contrib/windowmgrs/awm/RCS/Pause.c,v 1.2 89/02/07 21:23:15 jkh Exp $";
  35. X#endif    lint
  36. X
  37. X#include "X11/copyright.h"
  38. X/*
  39. X *
  40. X * Copyright 1987, 1988 by Ardent Computer Corporation, Sunnyvale, Ca.
  41. X *
  42. X * Copyright 1987 by Jordan Hubbard.
  43. X *
  44. X *
  45. X *                         All Rights Reserved
  46. X *
  47. X * Permission to use, copy, modify, and distribute this software and its
  48. X * documentation for any purpose and without fee is hereby granted,
  49. X * provided that the above copyright notice appear in all copies and that
  50. X * both that copyright notice and this permission notice appear in
  51. X * supporting documentation, and that the name of Ardent Computer
  52. X * Corporation or Jordan Hubbard not be used in advertising or publicity
  53. X * pertaining to distribution of the software without specific, written
  54. X * prior permission.
  55. X *
  56. X */
  57. X
  58. X/*
  59. X * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
  60. X *
  61. X *                         All Rights Reserved
  62. X *
  63. X * Permission to use, copy, modify, and distribute this software and its
  64. X * documentation for any purpose and without fee is hereby granted,
  65. X * provided that the above copyright notice appear in all copies and that
  66. X * both that copyright notice and this permission notice appear in
  67. X * supporting documentation, and that the name of Digital Equipment
  68. X * Corporation not be used in advertising or publicity pertaining to
  69. X * distribution of the software without specific, written prior permission.
  70. X *
  71. X *
  72. X * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  73. X * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  74. X * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  75. X * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  76. X * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  77. X * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  78. X * SOFTWARE.
  79. X */
  80. X
  81. X
  82. X
  83. X/*
  84. X * MODIFICATION HISTORY
  85. X *
  86. X * 000 -- M. Gancarz, DEC Ultrix Engineering Group
  87. X * 001 -- Loretta Guarino Reid, DEC Ultrix Engineering Group,
  88. X *  Western Software Lab. Convert to X11.
  89. X * 002 -- Jordan Hubbard, Ardent Computer
  90. X *  Changes for awm.
  91. X */
  92. X
  93. X#include "awm.h"
  94. X
  95. X/*ARGSUSED*/
  96. XBoolean Pause(window, mask, button, x, y)
  97. XWindow window;                          /* Event window. */
  98. Xint mask;                               /* Button/key mask. */
  99. Xint button;                           /* Button event detail. */
  100. Xint x, y;                               /* Event mouse position. */
  101. X{
  102. X    Entry("Pause")
  103. X
  104. X    XGrabServer(dpy);
  105. X    Leave(FALSE)
  106. X}
  107. X
  108. X/*ARGSUSED*/
  109. XBoolean Continue(window, mask, button, x, y)
  110. XWindow window;                          /* Event window. */
  111. Xint mask;                               /* Button/key mask. */
  112. Xint button;                           /* Button event detail. */
  113. Xint x, y;                               /* Event mouse position. */
  114. X{
  115. X    Entry("Continue")
  116. X
  117. X    XUngrabServer(dpy);
  118. X    Leave(FALSE)
  119. X}
  120. END_OF_FILE
  121. if test 3003 -ne `wc -c <'Pause.c'`; then
  122.     echo shar: \"'Pause.c'\" unpacked with wrong size!
  123. fi
  124. # end of 'Pause.c'
  125. fi
  126. if test -f 'awm.h' -a "${1}" != "-c" ; then 
  127.   echo shar: Will not clobber existing file \"'awm.h'\"
  128. else
  129. echo shar: Extracting \"'awm.h'\" \(22317 characters\)
  130. sed "s/^X//" >'awm.h' <<'END_OF_FILE'
  131. X#ifndef lint
  132. Xstatic char *rcsid_awm_h = "$Header: /usr/graph2/X11.3/contrib/windowmgrs/awm/RCS/awm.h,v 1.2 89/02/07 21:24:27 jkh Exp $";
  133. X#endif  lint
  134. X
  135. X#include <X11/copyright.h>
  136. X/*
  137. X *
  138. X * Copyright 1987, 1988 by Ardent Computer Corporation, Sunnyvale, Ca.
  139. X *
  140. X * Copyright 1987 by Jordan Hubbard.
  141. X *
  142. X *
  143. X *                         All Rights Reserved
  144. X *
  145. X * Permission to use, copy, modify, and distribute this software and its
  146. X * documentation for any purpose and without fee is hereby granted,
  147. X * provided that the above copyright notice appear in all copies and that
  148. X * both that copyright notice and this permission notice appear in
  149. X * supporting documentation, and that the name of Ardent Computer
  150. X * Corporation or Jordan Hubbard not be used in advertising or publicity
  151. X * pertaining to distribution of the software without specific, written
  152. X * prior permission.
  153. X *
  154. X */
  155. X
  156. X/*
  157. X * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
  158. X *
  159. X *                         All Rights Reserved
  160. X *
  161. X * Permission to use, copy, modify, and distribute this software and its
  162. X * documentation for any purpose and without fee is hereby granted,
  163. X * provided that the above copyright notice appear in all copies and that
  164. X * both that copyright notice and this permission notice appear in
  165. X * supporting documentation, and that the name of Digital Equipment
  166. X * Corporation not be used in advertising or publicity pertaining to
  167. X * distribution of the software without specific, written prior permission.
  168. X *
  169. X *
  170. X * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  171. X * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  172. X * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  173. X * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  174. X * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  175. X * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  176. X * SOFTWARE.
  177. X */
  178. X
  179. X/*
  180. X * MODIFICATION HISTORY
  181. X *
  182. X * 000 -- M. Gancarz, DEC Ultrix Engineering Group
  183. X * 001 -- R. Kittell, DEC Storage A/D May 19, 1986
  184. X *  Added global vars for warp options.
  185. X * 002 -- Loretta Guarino Reid, DEC Ultrix Engineering Group,
  186. X *  Western Software Lab, Port to X11
  187. X * 003 -- Jordan Hubbard, Ardent Computer
  188. X *  Many additional declarations for awm.
  189. X * 1.3 -- Support for WM_STATE (Mike Wexler)
  190. X */
  191. X#ifndef AWM_INCLUDE
  192. X#define AWM_INCLUDE
  193. X#include <errno.h>
  194. X#include <stdio.h>
  195. X#include <X11/Intrinsic.h>
  196. X#include <X11/Xatom.h>
  197. X
  198. X#include "menus/rtlmenu.h"
  199. X#include "support.h"
  200. X#define MIN(x, y)    ((x) <= (y) ? (x) : (y))
  201. X#define MAX(x, y)    ((x) >= (y) ? (x) : (y))
  202. X#define VOLUME_PERCENTAGE(x)    ((x)*14) 
  203. X#define ModMask 0xFF
  204. X#define ButtonMask(b)    (((b)==Button1) ? Button1Mask : \
  205. X              (((b)==Button2) ? Button2Mask : Button3Mask))
  206. X
  207. X#define DEF_DELTA        1
  208. X#define DEF_FUNC        GXcopy
  209. X#define DEF_ICON_BORDER_WIDTH     2
  210. X#define DEF_ICON_PAD        4
  211. X#define DEF_POP_BORDER_WIDTH     2
  212. X#define DEF_POP_PAD        4
  213. X#define DEF_MENU_BORDER_WIDTH     2
  214. X#define DEF_MENU_PAD        4
  215. X#define DEF_GADGET_PAD        3
  216. X#define DEF_GADGET_BORDER    1
  217. X#define DEF_TITLE_PAD        2
  218. X#define DEF_VOLUME        4
  219. X#define DEF_PUSH        5
  220. X#define DEF_BCONTEXT_WIDTH    0
  221. X#define DEF_RAISE_DELAY        100    /* milliseconds */
  222. X#define DEF_MAX_COLORS        0    /* 0 means take as many as we can */
  223. X#ifndef DEF_BCONTEXT_CURSOR
  224. X#define DEF_BCONTEXT_CURSOR    XC_plus
  225. X#endif    DEF_BCONTEXT_CURSOR
  226. X#ifndef    DEF_TITLE_CURSOR
  227. X#define DEF_TITLE_CURSOR    XC_left_ptr
  228. X#endif    DEF_TITLE_CURSOR
  229. X#ifndef    NAME
  230. X#define NAME            "awm"
  231. X#endif    NAME
  232. X#ifndef CLASS
  233. X#define    CLASS            "Wm"
  234. X#endif    CLASS
  235. X#ifndef    DEF_FONT
  236. X#define    DEF_FONT        "fixed"
  237. X#endif    DEF_FONT
  238. X#ifndef    DEF_TITLE_FONT
  239. X#define    DEF_TITLE_FONT        "8x13"
  240. X#endif    DEF_TITLE_FONT
  241. X#ifndef    DEF_ICON_FONT
  242. X#define    DEF_ICON_FONT        "8x13"
  243. X#endif    DEF_ICON_FONT
  244. X#ifndef    DEF_POPUP_FONT
  245. X#define    DEF_POPUP_FONT        "9x15"
  246. X#endif    DEF_POPUP_FONT
  247. X#ifndef    DEF_GADGET_FONT
  248. X#define DEF_GADGET_FONT        "fixed"
  249. X#endif    DEF_GADGET_FONT
  250. X#ifndef    DEF_MENU_FONT
  251. X#define    DEF_MENU_FONT        "8x13"
  252. X#endif    DEF_MENU_FONT
  253. X#ifndef    DEF_BOLD_FONT
  254. X#define    DEF_BOLD_FONT        "8x13bold"
  255. X#endif    DEF_BOLD_FONT
  256. X#define DEF_MENU_DELTA        20
  257. X#ifndef DEF_NAME
  258. X#define DEF_NAME        "NoName" /* for clients w/no name */
  259. X#endif
  260. X
  261. X#define INIT_PTEXT        {'0', '0', '0', 'x', '0', '0', '0'}
  262. X
  263. X#ifndef TEMPFILE
  264. X#define TEMPFILE        "/tmp/awm.XXXXXX"
  265. X#endif    TEMPFILE
  266. X
  267. X#define CURSOR_WIDTH        16
  268. X#define CURSOR_HEIGHT        16
  269. X#define MAX_ZAP_VECTORS        8
  270. X#define MAX_BOX_VECTORS        20
  271. X#define DRAW_WIDTH        0     /* use fastest hardware draw */
  272. X#define DRAW_VALUE        0xfd
  273. X#define DRAW_FUNC        GXxor
  274. X#define DRAW_PLANES        1
  275. X
  276. X#define NOCOLOR            -1
  277. X
  278. X/*
  279. X * The first BITS_USED bits of the mask are used to define the most generic
  280. X * types. All other bits are free for storing peripheral information.
  281. X * For now, we use the extra bits to specify which gadget(s) are bound
  282. X * to an action. MAX_GADGETS depends on BITS_USED to determine the maximum
  283. X * number of gadgets possible. If you add a new context type, be sure to
  284. X * increment BITS_USED.
  285. X */
  286. X#define ROOT            0x1
  287. X#define WINDOW            0x2
  288. X#define ICON            0x4
  289. X#define TITLE            0x8
  290. X#define BORDER            0x10
  291. X#define GADGET            0x20
  292. X
  293. X#define BITS_USED        6
  294. X
  295. X/* Window states */
  296. X#define ST_WINDOW    0x1
  297. X#define ST_ICON        0x2
  298. X#define ST_PLACED    0x4
  299. X#define ST_DECORATED    0x8
  300. X
  301. X#define DECORATED(a) (a && (a->state & ST_DECORATED))
  302. X
  303. X/* Window attributes */
  304. X#define AT_NONE        0x0
  305. X#define AT_TITLE    0x1
  306. X#define AT_GADGETS    0x2
  307. X#define AT_RAISE    0x4
  308. X#define AT_BORDER    0x8
  309. X#define AT_INPUT    0x10
  310. X#define AT_ICONLABEL    0x20
  311. X
  312. X/*
  313. X * Gadgets aren't the sort of embellishments that one uses in quantitity
  314. X * (unless one is designing a truly odd interface), so we keep the information
  315. X * in an array instead of using the usual linked list. MAX_GADGETS is a derived
  316. X * macro (see BITS_USED) that is used to determine the size of the
  317. X * Array.
  318. X *
  319. X */
  320. X#define MAX_GADGETS        ((sizeof(int) * 8) - BITS_USED)
  321. X
  322. X#ifndef FAILURE
  323. X#define FAILURE    0
  324. X#endif    FAILURE
  325. X
  326. X#define NAME_LEN        256L    /* Maximum length string names */
  327. X#define EVENTMASK        (ButtonPressMask | ButtonReleaseMask)
  328. X
  329. X
  330. X#define DrawBox() XDrawSegments(dpy, RootWindow(dpy, scr),DrawGC,box,num_vectors)
  331. X#define DrawZap() XDrawSegments(dpy, RootWindow(dpy, scr),DrawGC,zap,num_vectors)
  332. X
  333. X#define gray_width 16
  334. X#define gray_height 16
  335. Xextern char gray_bits[];
  336. X
  337. X#define solid_width 16
  338. X#define solid_height 16
  339. Xextern char solid_bits[];
  340. X#define xlogo32_width 32
  341. X#define xlogo32_height 32
  342. Xextern char xlogo32_bits[];
  343. X
  344. X/*
  345. X * All one needs to know about an awm managed window.. (so far...)
  346. X */
  347. X#ifdef WMSTATE
  348. X#define WithdrawState    0
  349. X#define NormalState    1
  350. X#define IconicState    3
  351. X
  352. Xtypedef struct {
  353. X  int state;
  354. X  Window icon;
  355. X} WM_STATE;
  356. X
  357. Xextern Atom wm_state_atom;
  358. X#endif /* WMSTATE */
  359. X
  360. X
  361. Xtypedef struct _awminfo {
  362. X     Window title, client, frame, icon;    /* Associated windows */
  363. X     Window *gadgets;            /* associated gadgets */
  364. X     char *name;            /* The formatted window name */
  365. X     Boolean own;            /* Do we own the icon window? */
  366. X     Pixmap back, bold, iconPixmap;    /* background, bold and icon pix */
  367. X     Pixmap BC_back, BC_bold;        /* BC back and bold pixmaps */
  368. X#ifdef RAINBOW
  369. X     /* Per window versions of the globals colours */
  370. X     Pixmap grayPixmap, solidPixmap;
  371. X     Pixmap iBackPixmap;
  372. X     Pixel foreColor, backColor;
  373. X     Pixel iBorder;
  374. X     Pixel iBackground, iForeground;
  375. X     Pixel iTextForeground, iTextBackground;
  376. X#endif
  377. X     unsigned int border_width;        /* original border width */
  378. X     int state;                /* The state of the window */
  379. X     int attrs;                /* Window "attributes" */
  380. X     GC winGC;                /* GC at proper depth for window */
  381. X#ifdef WMSTATE
  382. X     WM_STATE wm_state;
  383. X#endif /* WMSTATE */
  384. X} AwmInfo, *AwmInfoPtr;
  385. X
  386. X/*
  387. X * This whole section has changed substantially. Basically, since all the
  388. X * variables have vanished into the resource manager, the keyword table
  389. X * only needs to keep track of function pointers, boolean pointers and
  390. X * "special" keywords like menu and gagdet. Since some things are still
  391. X * modifiable from menus (only booleans, currently, though this will change),
  392. X * we keep these in the keyword table even though
  393. X * they're no longer directly modifable from the .awmrc
  394. X */
  395. X
  396. X/*
  397. X * Keyword table entry.
  398. X */
  399. Xtypedef struct _keyword {
  400. X     char *name;
  401. X     int type;
  402. X     Boolean *bptr;
  403. X     Boolean (*fptr)();
  404. X} Keyword;
  405. X
  406. X/*
  407. X * Keyword table type entry.
  408. X */
  409. X#define IsFunction    1
  410. X#define IsMenuMap    2
  411. X#define IsMenu        3
  412. X#define IsDownFunction    4
  413. X#define IsParser    5
  414. X#define IsQuitFunction    6
  415. X#define IsGadget    7
  416. X#define IsBoolean    8
  417. X#define IsAction    9
  418. X
  419. X/*
  420. X * Button/key binding type.
  421. X */
  422. Xtypedef struct _binding {
  423. X    struct _binding *next;
  424. X    int context;
  425. X    unsigned int mask;
  426. X    int button;
  427. X    Boolean (*func)();
  428. X    char *menuname;
  429. X    RTLMenu menu;
  430. X} Binding;
  431. X/*
  432. X * Key expression type.
  433. X */
  434. Xtypedef struct _keyexpr {
  435. X    char *name;
  436. X    int mask;
  437. X} KeyExpr;
  438. X/*
  439. X * Context expression type.
  440. X */
  441. Xtypedef struct _contexpr {
  442. X    char *name;
  443. X    int mask;
  444. X} ContExpr;
  445. X
  446. X/*
  447. X * Button modifier type.
  448. X */
  449. Xtypedef struct _buttonmodifier {
  450. X    char *name;
  451. X    int mask;
  452. X} ButtonModifier;
  453. X
  454. X/*
  455. X * Gravity expression type.
  456. X */
  457. Xtypedef struct _gravityexpr {
  458. X     char *name;
  459. X     int mask;
  460. X} GravityExpr;
  461. X
  462. X/*
  463. X * Button modifier mask definitions.
  464. X * bits 13 and 14 unused in key masks, according to X.h
  465. X * steal bit 15, since we don't use AnyModifier
  466. X */
  467. X
  468. X#define DeltaMotion    (1<<13)
  469. X#define ButtonUp    (1<<14)
  470. X#define ButtonDown    AnyModifier
  471. X#define ButtonMods    DeltaMotion+ButtonUp+ButtonDown
  472. X
  473. X/* 
  474. X * Button and mask redefinitions, for X11
  475. X */
  476. X#define LeftMask     Button1Mask
  477. X#define MiddleMask     Button2Mask
  478. X#define RightMask     Button3Mask
  479. X#define LeftButton    Button1
  480. X#define MiddleButton    Button2
  481. X#define RightButton    Button3
  482. X
  483. X/*
  484. X * Declaration specific information for gadgets. This defines only gadget
  485. X * types, not the actual gadgets. The pixmap member is only used if a pixmap
  486. X * is being displayed. Gravity and offset are purely optional.
  487. X */
  488. X
  489. X#define NoGadgetGravity        0
  490. X#define LeftGadgetGravity    1
  491. X#define RightGadgetGravity    2
  492. X#define CenterGadgetGravity    3
  493. X
  494. Xtypedef struct _gadgetdecl {    /*   Declaration (type) information */
  495. X     unsigned char *name;    /* Either text label or pixmap file name */
  496. X     unsigned char *data;    /* If pixmap file, this is the data from it */
  497. X     char *forecolor;        /* foreground color for pixmap */
  498. X     char *backcolor;        /* background color for pixmap */
  499. X     XFontStruct *fontInfo;    /* font for text */
  500. X     int high, wide;        /* width and height of pixmap or text */
  501. X     int gravity;        /* stick to the left or right? */
  502. X     int offset;        /* offset from previous item */
  503. X} GadgetDecl;
  504. X
  505. X/*
  506. X * MenuInfo data type.
  507. X */
  508. Xtypedef struct _menuinfo {
  509. X    char *name;            /* Name of this menu. */
  510. X    char *pixmapname;        /* Name of label pixmap (opt) */
  511. X    RTLMenu menu;        /* RTL menu handle for destroy */
  512. X    struct _actionline *line;    /* Linked list of menu items. */
  513. X} MenuInfo;
  514. X/*
  515. X * Action Line data type.
  516. X */
  517. Xtypedef struct _actionline {
  518. X    struct _actionline *next;    /* Pointer to next line. */
  519. X    char *name;            /* Name of this line. */
  520. X    char *pixmapname;        /* Name of the backing pixmap (opt) */
  521. X    int type;            /* IsShellCommand, IsText, IsTextNL... */
  522. X    RTLMenuItem item;        /* RTL item handle */
  523. X    char *text;            /* Text string to be acted upon. */
  524. X    Boolean (*func)();        /* Window manager function to be invoked. */
  525. X} ActionLine;
  526. X/*
  527. X * ActionLine->type definitions.
  528. X */
  529. X#define IsShellCommand        1
  530. X#define IsText            2
  531. X#define IsTextNL        3
  532. X#define IsUwmFunction        4
  533. X#define IsMenuFunction        5
  534. X#define IsImmFunction        6    /* Immediate (context-less) function. */
  535. X#define IsVar            7    /* we're setting a boolean variable */
  536. X/*
  537. X * Menu Link data type.  Used by the parser when creating a linked list
  538. X * of menus. 
  539. X */
  540. Xtypedef struct _menulink {
  541. X    struct _menulink *next;    /* Pointer to next MenuLink. */
  542. X    struct _menuinfo *menu;    /* Pointer to the menu in this link. */
  543. X} MenuLink;
  544. X
  545. X/*
  546. X * External variable definitions.
  547. X */
  548. Xextern int errno;
  549. Xextern Window Pop;        /* Pop-up dimension display window. */
  550. Xextern Window Frozen;        /* Contains window id of "gridded" window. */
  551. Xextern XFontStruct *IFontInfo;    /* Icon text font information. */
  552. Xextern XFontStruct *PFontInfo;    /* Pop-up text font information. */
  553. Xextern XFontStruct *TFontInfo;    /* Title text font information. */
  554. Xextern XFontStruct *TFontBoldInfo;/* Title text (bold) font information. */
  555. Xextern XFontStruct *GFontInfo; /* Gadget box text font */
  556. Xextern XFontStruct *MFontInfo;    /* Menu font */
  557. Xextern XFontStruct *MBoldFontInfo;/* Menu bold font */
  558. Xextern Pixmap GrayPixmap;    /* Gray pixmap. */
  559. Xextern Pixmap SolidPixmap;
  560. Xextern Pixmap IBackPixmap;    /* Icon window background pixmap. */
  561. Xextern Pixmap IDefPixmap;    /* Icon pixmap for twm style icons */
  562. Xextern char *BForeground;    /* Border Context (pixmap) foreground pixel */
  563. Xextern char *BBackground;    /* Border Context (pixmap) background pixel */
  564. Xextern char *WBorder;        /* Window border pixel */
  565. Xextern char *TTextForeground;    /* Title text foreground pixel */
  566. Xextern char *TTextBackground;    /* Title text background pixel */
  567. Xextern char *TForeground;    /* Title (pixmap) foreground pixel */
  568. Xextern char *TBackground;    /* Title (pixmap) background pixel */
  569. Xextern char *Foreground;    /* default forground color (text) */
  570. Xextern char *Background;    /* default background color (text) */
  571. Xextern Pixel IBorder;        /* Icon window border pixel. */
  572. Xextern Pixel ITextForeground;    /* Icon window text forground color. */
  573. Xextern Pixel ITextBackground;    /* Icon window text background color. */
  574. Xextern Pixel IForeground;    /* Icon pixmap foreground color */
  575. Xextern Pixel IBackground;    /* Icon pixmap background color */
  576. Xextern Pixel PForeground;    /* Pop-up window forground color. */
  577. Xextern Pixel PBackground;    /* Pop-up window background color. */
  578. Xextern Pixel PBorder;        /* Pop-Up Window border pixel. */
  579. Xextern Pixel ForeColor;        /* default foreground color */
  580. Xextern Pixel BackColor;        /* default background color */
  581. Xextern Pixel MBorder;        /* Menu border color */
  582. Xextern Pixel MForeground;    /* Menu foreground color */
  583. Xextern Pixel MBackground;    /* Menu background color */
  584. Xextern Cursor ArrowCrossCursor; /* Arrow cross cursor. */
  585. Xextern Cursor TextCursor;    /* Text cursor used in icon windows. */
  586. Xextern Cursor IconCursor;    /* Icon Cursor. */
  587. Xextern Cursor LeftButtonCursor;    /* Left button main cursor. */
  588. Xextern Cursor MiddleButtonCursor;/* Middle button main cursor. */
  589. Xextern Cursor RightButtonCursor;/* Right button main cursor. */
  590. Xextern Cursor TargetCursor;    /* Target (select-a-window) cursor. */
  591. Xextern Cursor TitleCursor;    /* Title bar cursor */
  592. Xextern Cursor FrameCursor;    /* Frame cursor */
  593. Xextern Cursor GumbyCursor;    /* Used in icons if not type-in   */
  594. Xextern unsigned int GadgetBorder;    /* Width of gadget borders */
  595. Xextern int ScreenWidth;        /* Display screen width. */
  596. Xextern int ScreenHeight;    /* Display screen height. */
  597. Xextern int TitleHeight;        /* Height in pixels of title bar(s) */
  598. Xextern int titleHeight;        /* Derived height of title bar(s) */
  599. Xextern int gadgetHeight;    /* Height of highest gadget */
  600. Xextern int NameOffset;        /* Offset for window name */
  601. Xextern int IBorderWidth;    /* Icon window border width. */
  602. Xextern int PWidth;        /* Pop-up window width (including borders). */
  603. Xextern int PHeight;        /* Pop-up window height (including borders). */
  604. Xextern unsigned int PBorderWidth;    /* Pop-up window border width. */
  605. Xextern int PPadding;        /* Pop-up window padding. */
  606. Xextern int Delta;        /* Mouse movement slop. */
  607. Xextern int HIconPad;        /* Icon horizontal padding. */
  608. Xextern int VIconPad;        /* Icon vertical padding. */
  609. Xextern int Pushval;        /* Number of pixels to push window by. */
  610. Xextern int BContext;        /* Width of border context area in pixels */
  611. Xextern int RaiseDelay;        /* Delay in milliseconds before autoraising windows */
  612. Xextern int Volume;        /* Audible alarm volume. */
  613. Xextern int NumGadgets;        /* Number of gadgets used */
  614. Xextern int GadgetPad;        /* Padding between gadgets */
  615. Xextern int TitlePad;        /* Title text padding */
  616. Xextern int status;        /* Routine return status. */
  617. Xextern int MPad;        /* menu padding */
  618. Xextern int MDelta;        /* Menu subitem delta */
  619. Xextern int MBorderWidth;    /* Menu border width */
  620. Xextern int MItemBorder;        /* Menu item border width */
  621. Xextern unsigned int BCursor;    /* Border context cursor */
  622. Xextern unsigned int TCursor;    /* Title context cursor */
  623. Xextern MenuLink *Menus;        /* Linked list of menus. */
  624. Xextern GC  IconGC;        /* graphics context for icon */
  625. Xextern GC  PopGC;        /* graphics context for pop */
  626. Xextern GC  DrawGC;        /* graphics context for zap */
  627. X
  628. Xextern Boolean Autoraise;    /* Raise window on input focus? */
  629. Xextern Boolean Autoselect;    /* Warp mouse to default menu selection? */
  630. Xextern Boolean Borders;        /* Display border context areas? */
  631. Xextern Boolean ConstrainResize;    /* Don't resize until pointer leaves window */
  632. Xextern Boolean Freeze;        /* Freeze server during move/resize? */
  633. Xextern Boolean Grid;        /* Should the m/r box contain a 9 seg. grid. */
  634. Xextern Boolean Hilite;        /* Should we highlight titles on focus? */
  635. Xextern Boolean BorderHilite;    /* Should we highlight borders on focus? */
  636. Xextern Boolean FrameFocus;    /* Should frame be considered part of window */
  637. Xextern Boolean ShowName;    /* Display names in title bars */
  638. Xextern Boolean NWindow;        /* Normalize windows? */
  639. Xextern Boolean NIcon;        /* Normalize icons? */
  640. Xextern Boolean RootResizeBox;    /* Should resize box obscure window? */
  641. Xextern Boolean InstallColormap;    /* Install colormap for clients? */
  642. Xextern Boolean Push;        /* Relative=TRUE, Absolute=FALSE. */
  643. Xextern Boolean ResizeRelative;    /* Relative=TRUE, Absolute=FALSE. */
  644. Xextern Boolean Reverse;        /* Reverse video? */
  645. Xextern Boolean SaveUnder;    /* Save unders? */
  646. Xextern Boolean Snatched;    /* We're in the middle of an no-highlight/raise op */
  647. Xextern Boolean Titles;        /* Title bars on windows? */
  648. Xextern Boolean IconLabels;    /* Labels on pixmap icons? (twm style) */
  649. Xextern Boolean ILabelTop;    /* label top of icon? */
  650. Xextern Boolean PushDown;    /* Down=TRUE, Up=FALSE */
  651. Xextern Boolean UseGadgets;    /* Gadget boxes in title bars? */
  652. Xextern Boolean Wall;        /* Don't allow windows past edges of screen */
  653. Xextern Boolean WarpOnRaise;    /* Warp to upper right corner on raise. */
  654. Xextern Boolean WarpOnIconify;   /* Warp to icon center on iconify. */
  655. Xextern Boolean WarpOnDeIconify; /* Warp to upper right corner on de-iconify. */
  656. Xextern Boolean Zap;        /* Should the the zap effect be used. */
  657. Xextern Boolean FocusSetByUser;  /* True if f.focus called */
  658. Xextern Boolean FocusSetByWM;    /* True if awm set the focus */
  659. Xextern char PText[];        /* Pop-up window dummy text. */
  660. Xextern int PTextSize;        /* Pop-up window dummy text size. */
  661. X
  662. Xextern int Lineno;        /* Line count for parser. */
  663. Xextern Boolean Startup_File_Error; /* Startup file error flag. */
  664. Xextern char Startup_File[];    /* Startup file name. */
  665. Xextern char *IFontName;        /* Icon font name. */
  666. Xextern char *PFontName;        /* Pop-up font name. */
  667. Xextern char *TFontName;        /* Title font name. */
  668. Xextern char *GFontName;        /* Gadget font name */
  669. Xextern char *TFontBoldName;    /* Bold Title font name. */
  670. Xextern char *TBoldPixmapName;    /* Title (highlighted) pixmap file */
  671. Xextern char *TBackPixmapData;    /* Bitmap data file title background */
  672. Xextern char *TBoldPixmapData;    /* ditto, except highlighted */
  673. Xextern char *BBackPixmapData;    /* Border Context area background pixmap data */
  674. Xextern char *BBoldPixmapData;    /* Border Context bold pixmap data */
  675. Xextern char *awmPath;        /* Pathlist for pixmap files */
  676. Xextern char **Argv;        /* Pointer to command line parameters. */
  677. Xextern char **Environ;        /* Pointer to environment. */
  678. Xextern char *DefaultBindings[];    /* Default bindings string array. */
  679. Xextern Keyword KeywordTable[];    /* Keyword lookup table. */
  680. Xextern Binding *Blist;        /* Button/key bindings list. */
  681. Xextern KeyExpr KeyExprTbl[];    /* Key expression table. */
  682. Xextern ContExpr ContExprTbl[];    /* Context expression table. */
  683. Xextern ButtonModifier ButtModTbl[];/* Button modifier table. */
  684. Xextern GravityExpr GravityExprTbl[]; /* Gravity expression table. */
  685. X
  686. Xextern GadgetDecl **Gadgets;    /* Gadgets declared. See gram.y */
  687. Xextern int scr;
  688. Xextern Display *dpy;        /* Display info pointer. */
  689. X#ifdef PROFIL
  690. Xint ptrap();
  691. X#endif
  692. X/*
  693. X * External routine typing.
  694. X */
  695. Xextern Boolean Beep();
  696. Xextern Boolean CircleDown();
  697. Xextern Boolean CircleUp();
  698. Xextern Boolean Continue();
  699. Xextern Boolean Focus();
  700. Xextern Boolean UnFocus();
  701. Xextern Boolean GetButton();
  702. Xextern Boolean Iconify();
  703. Xextern Boolean Lower();
  704. Xextern Boolean DoMenu();
  705. Xextern Boolean DoAction();
  706. Xextern Boolean Lock();
  707. Xextern Boolean Move();
  708. Xextern Boolean MoveOpaque();
  709. Xextern Boolean Neaten();
  710. Xextern Boolean NewIconify();
  711. Xextern Boolean Pause();
  712. Xextern Boolean ShoveDown();
  713. Xextern Boolean ShoveLeft();
  714. Xextern Boolean ShoveRight();
  715. Xextern Boolean ShoveUp();
  716. Xextern Boolean Quit();
  717. Xextern Boolean Raise();
  718. Xextern Boolean Redraw();
  719. Xextern Boolean Refresh();
  720. Xextern Boolean ResetBindings();
  721. Xextern Boolean ResetMenus();
  722. Xextern Boolean ResetGadgets();
  723. Xextern Boolean Resize();
  724. Xextern Boolean Restart();
  725. Xextern Boolean FDecorate();
  726. Xextern Boolean FNoDecorate();
  727. Xextern Boolean DestroyClient();
  728. Xextern Boolean GetBoolRes();
  729. Xextern Boolean ConfigureWindow();
  730. Xextern int StoreCursors();
  731. Xextern int StoreBox();
  732. Xextern int StoreTitleBox();
  733. Xextern int StoreGridBox();
  734. Xextern int StoreTitleGridBox();
  735. Xextern int StoreZap();
  736. Xextern int Error();
  737. Xextern int XError();
  738. Xextern int GetIntRes();
  739. Xextern Window Reparent(), Decorate();
  740. Xextern unsigned char *expand_metachars();
  741. Xextern char *stash();
  742. Xextern char *GetIconName();
  743. Xextern char *expand_from_path();
  744. Xextern char *GetStringRes();
  745. Xextern char *GetPixmapDataRes();
  746. Xextern Pixmap GetPixmapRes();
  747. Xextern Pixel GetColorRes();
  748. Xextern Pixel GetPixel();
  749. Xextern XFontStruct *GetFontRes();
  750. Xextern Drawable GetPixmapFromCache();
  751. Xextern AwmInfoPtr GetAwmInfo();
  752. Xextern AwmInfoPtr RegisterWindow();
  753. Xextern AwmInfoPtr IsTitled();
  754. Xextern AwmInfoPtr IsGadgetWin();
  755. X
  756. Xextern void Init_Titles(), Init_Frames();
  757. Xextern void NoDecorate();
  758. Xextern void PaintTitle();
  759. Xextern void SetBorderPixmaps();
  760. Xextern void FreePixmapFromCache();
  761. X
  762. X#ifdef    NEATEN
  763. X#define DEFAULT_ABS_MIN        64
  764. X#define SEPARATION        2
  765. X#define DEF_PRIMARY_PLACEMENT    "Top"
  766. X#define DEF_SECONDARY_PLACEMENT    "Left"
  767. X
  768. Xextern int AbsMinWidth;
  769. Xextern int AbsMinHeight;
  770. Xextern Boolean RetainSize;
  771. Xextern Boolean KeepOpen;
  772. Xextern Boolean Fill;
  773. Xextern Boolean UsePriorities;
  774. Xextern Boolean FixTopOfStack;
  775. Xextern char *PrimaryIconPlacement;
  776. Xextern char *SecondaryIconPlacement;
  777. X#endif    NEATEN
  778. X#endif AWM_INCLUDE
  779. END_OF_FILE
  780. if test 22317 -ne `wc -c <'awm.h'`; then
  781.     echo shar: \"'awm.h'\" unpacked with wrong size!
  782. fi
  783. # end of 'awm.h'
  784. fi
  785. if test -f 'menus/track_menu.c' -a "${1}" != "-c" ; then 
  786.   echo shar: Will not clobber existing file \"'menus/track_menu.c'\"
  787. else
  788. echo shar: Extracting \"'menus/track_menu.c'\" \(26567 characters\)
  789. sed "s/^X//" >'menus/track_menu.c' <<'END_OF_FILE'
  790. X
  791. X#ifndef lint
  792. X     static char sccs_id[] = "@(#)track_menu.c    2.1 12/16/87  Siemens Corporate Research and Support, Inc.";
  793. X#endif
  794. X
  795. X
  796. X#include "X11/copyright.h"
  797. X
  798. X/* 
  799. X  RTL Menu Package Version 1.0
  800. X  by Joe Camaratta and Mike Berman, Siemens RTL, Princeton NJ, 1987
  801. X  
  802. X  track_menu.c: bring up menus and track the mouse
  803. X  */
  804. X
  805. X/*
  806. X *
  807. X * Copyright 1987, 1988 by Ardent Computer Corporation, Sunnyvale, Ca.
  808. X *
  809. X * Copyright 1987 by Jordan Hubbard.
  810. X *
  811. X *
  812. X *                         All Rights Reserved
  813. X *
  814. X * Permission to use, copy, modify, and distribute this software and its
  815. X * documentation for any purpose and without fee is hereby granted,
  816. X * provided that the above copyright notice appear in all copies and that
  817. X * both that copyright notice and this permission notice appear in
  818. X * supporting documentation, and that the name of Ardent Computer
  819. X * Corporation or Jordan Hubbard not be used in advertising or publicity
  820. X * pertaining to distribution of the software without specific, written
  821. X * prior permission.
  822. X *
  823. X */
  824. X
  825. X
  826. X/*
  827. X  
  828. X  Copyright 1987 by
  829. X  Siemens Corporate Research and Support, Inc., Princeton, New Jersey
  830. X  
  831. X  Permission to use, copy, modify, and distribute this software
  832. X  and its documentation for any purpose and without fee is
  833. X  hereby granted, provided that the above copyright notice
  834. X  appear in all copies and that both that copyright notice and
  835. X  this permission notice appear in supporting documentation, and
  836. X  that the name of Siemens not be used in advertising or
  837. X  publicity pertaining to distribution of the software without
  838. X  specific, written prior permission.  Siemens makes no
  839. X  representations about the suitability of this software for any
  840. X  purpose.  It is provided "as is" without express or implied
  841. X  warranty.
  842. X  
  843. X  */
  844. X
  845. X/*
  846. X * The menu package will break if you don't define this, but
  847. X * it's there in case you want to see just how and where the
  848. X * "eventstack" stuff is used and, if necessary, replace it.
  849. X */
  850. X#define SAVE_EVENTS
  851. X
  852. X
  853. X#include <stdio.h>
  854. X#include "X11/Xlib.h"
  855. X#include "X11/cursorfont.h"
  856. X#include "arrow_icon.h"
  857. X#include "null_icon.h"
  858. X#include "menu.h"
  859. X#include "menu.def.h"
  860. X#include "menu.ext.h"
  861. X#include "dbug.h"
  862. X#ifdef SAVE_EVENTS
  863. X#include "eventstack.h"
  864. X#endif
  865. X
  866. X#define MIN(x,y) (((x) <= (y))? x:y)
  867. X#define MAX(x,y) (((x) >= (y))? x:y)
  868. X
  869. X#define CLICK_TIME 290 /* in milliseconds */
  870. X
  871. X#define CursorLockMask (ButtonReleaseMask | ExposureMask)
  872. X
  873. X/* Event macros */
  874. X
  875. X#define EventGetXCoord(rep) ((rep).xmotion.x)
  876. X#define EventGetYCoord(rep) ((rep).xmotion.y)
  877. X#define EventType(rep) ((rep).type)
  878. X#define EventXWindow(rep) ((rep).xcrossing.window)
  879. X#define EventXTime(rep) ((rep).xcrossing.time)
  880. X#define EventXMode(rep) ((rep).xcrossing.mode)
  881. X#define EventXRootX(rep) ((rep).xcrossing.x_root)
  882. X#define EventXRootY(rep) ((rep).xcrossing.y_root)
  883. X#define EventXDetail(rep) ((rep).xcrossing.detail)
  884. X#define EventMWindow(rep) ((rep).xmotion.window)
  885. X#define EventMTime(rep) ((rep).xmotion.time)
  886. X#define EventButton(rep) ((rep).xbutton.button)
  887. X#define EventBWindow(rep) ((rep).xbutton.window)
  888. X#define EventBTime(rep) ((rep).xbutton.time)
  889. X#define EventEX(rep) ((rep).xexpose.x)
  890. X#define EventEY(rep) ((rep).xexpose.y)
  891. X#define EventEWidth(rep) ((rep).xexpose.width)
  892. X#define EventEHeight(rep) ((rep).xexpose.height)
  893. X#define PointerEvent(rep) \
  894. X     ((EventType(rep) == ButtonPress) || \
  895. X      (EventType(rep) == ButtonRelease) || \
  896. X      (EventType(rep) == MotionNotify) || \
  897. X      (EventType(rep) == EnterNotify) || \
  898. X      (EventType(rep) == LeaveNotify) || \
  899. X      (EventType(rep) == FocusIn) || \
  900. X      (EventType(rep) == FocusOut))
  901. X#define KeyEvent(rep) \
  902. X     ((EventType(rep) == KeyPress) || (EventType(rep) == KeyRelease))
  903. X/* Possible states for the state machine */
  904. Xtypedef enum
  905. X{
  906. X     Initial,      /* Inside a submenu, but not any item */
  907. X     CheckTrigger, /* Inside an item that has submenu, checking for pullright */
  908. X     Leaf,         /* Inside an item with no submenu */
  909. X     Exit,         /* Preparing to exit */
  910. X     LevelControl  /* Not in any submenu, waiting to enter something */
  911. X     } State;
  912. X
  913. XState InitialState(), CheckTriggerState(), LeafState(), LevelControlState(),
  914. X     GetItemState();
  915. XBoolean EventNotSignificant(), PushSubmenu();
  916. X
  917. Xvoid OutputEvent(), GetNextSignificantEvent(), PopSubmenu(), 
  918. X     Highlight(), Unhighlight(), DisplayInitialMenus(), LockCursor(),
  919. X     TossExtraMoves(), UnlockCursor();
  920. X
  921. Xvoid ProcessExposeEvents();
  922. X
  923. Xvoid SaveTest();
  924. X
  925. XMenuItem *MenuGetItem();
  926. XMenu *MenuGetMenu();
  927. X
  928. X/* global state variables */
  929. X
  930. Xstatic MenuItem *current_item;
  931. Xstatic Menu *current_menu;
  932. Xstatic Window root_window;
  933. Xextern Display *dpy;
  934. Xextern int scr;
  935. Xstatic int level;            /* submenu level */
  936. Xstatic Time button_time;     /* time button press invoked */
  937. Xstatic Cursor wait_cursor = None;  /* empty cursor for lock state */
  938. Xstatic Boolean click_allowed;
  939. Xstatic Boolean lock_event_mask, unlock_event_mask;
  940. X
  941. Xextern Boolean Autoselect;
  942. Xextern int MDelta;
  943. X
  944. X#ifdef SAVE_EVENTS
  945. Xstatic struct Ev_q *ev_save = 0;
  946. X#endif
  947. X
  948. X
  949. XMenuItem *TrackMenu(root_menu, root_x, root_y, 
  950. X            init_button, root, buttime)
  951. XMenu *root_menu;    /* Pointer to root menu requested to pop up   */
  952. Xint root_x, root_y; /* Position to start menu                     */
  953. Xint init_button;    /* The # of button used to pop up menu        */
  954. XWindow root;        /* Window label for parent of menu            */
  955. XTime buttime;       /* timestamp for button (or 0, if CLICK == 0) */
  956. X{
  957. X     State CurrentState = LevelControl;
  958. X     XEvent Event_Reply;
  959. X     int open_x;
  960. X     Boolean selected = FALSE;
  961. X     MenuItem *selected_item;
  962. X     
  963. X     Entry("TrackMenu")
  964. X     
  965. X     /* Initialize globals */
  966. X     
  967. X     button_time = buttime;
  968. X     root_window = root;
  969. X     level = 0;
  970. X     current_menu = root_menu;
  971. X     click_allowed = (TestOptionFlag(current_menu, clickokay))? TRUE : FALSE;
  972. X     unlock_event_mask = (TestOptionFlag(current_menu, savebits))?
  973. X      MenuEventMask : (MenuEventMask | ExposureMask);
  974. X     lock_event_mask = (TestOptionFlag(current_menu, savebits))?
  975. X      CursorLockMask : (CursorLockMask | ExposureMask);
  976. X     
  977. X     /* If not already done, set up the null cursor for lock state */
  978. X     if (wait_cursor == None)
  979. X     {
  980. X      Pixmap wc_pixmap;
  981. X      XColor fg, bg;
  982. X      
  983. X      wc_pixmap = XCreateBitmapFromData (dpy, root_window,
  984. X                         null_icon_bits,
  985. X                         null_icon_width, null_icon_height);
  986. X      wait_cursor = XCreatePixmapCursor (dpy, wc_pixmap, wc_pixmap,
  987. X                         &fg, &bg, 1, 1);
  988. X     }
  989. X     
  990. X     
  991. X     /* Block all other action by grabbing the server */
  992. X     /*    XGrabServer (dpy); */
  993. X     /* Don't think we need to grab the server... so for now, we won't */
  994. X     
  995. X#ifdef SAVE_EVENTS     
  996. X     /* Get the present state, so it can be restored later */
  997. X     /* Any events on the queue when we start get saved now, restored later */
  998. X     SaveEvents (dpy, &ev_save, ~(unsigned long) ButtonReleaseMask);
  999. X#endif
  1000. X     
  1001. X     LockCursor(root_window);
  1002. X     if (!(current_item =
  1003. X       Display_Menu(current_menu, NULLMENU, root_x, root_y)))
  1004. X     {
  1005. X      CurrentState = Exit;
  1006. X     }
  1007. X     /*
  1008. X      * First item is a label and autoselect is on, so we want
  1009. X      * to push on to the first "real" item.
  1010. X      */
  1011. X     if (ItemIsDeaf(current_item) && Autoselect)
  1012. X      current_item = current_item->nextItem;
  1013. X     LockCursor(ItemWindow(current_item));
  1014. X     open_x = root_x;
  1015. X     
  1016. X     /* Push to appropriate previous item, if any */
  1017. X     while (MenuHasInitialItem(current_menu) && (CurrentState != Exit))
  1018. X     {
  1019. X      current_item = GetInitialItem(current_menu);
  1020. X      ClearInitialItem(current_menu);
  1021. X      
  1022. X      /* if the initial item can't be selected, take first in list */
  1023. X      if (ItemIsNull(current_item) || ItemIsDisabled(current_item))
  1024. X      {
  1025. X           current_item = MenuItems(current_menu);
  1026. X           break;
  1027. X      }
  1028. X      else if (ItemIsLeaf(current_item)) /* then we're done */
  1029. X           break;
  1030. X      else
  1031. X      {
  1032. X           open_x += ItemGetArrowPosition(current_item);
  1033. X           if (!ItemIsDeaf(current_item))
  1034. X            Highlight(current_item);
  1035. X           TossExtraMoves(ItemWindow(current_item));
  1036. X           (void)PushSubmenu(open_x);
  1037. X      }
  1038. X     }
  1039. X     ProcessExposeEvents();
  1040. X     if (CurrentState != Exit)
  1041. X      CurrentState = (ItemIsLeaf(current_item)) ? Leaf : CheckTrigger;
  1042. X     if (!ItemIsDeaf(current_item))
  1043. X      Highlight(current_item);
  1044. X     XSync (dpy, 0);  /* get release click, if it's in queue */
  1045. X#ifdef SAVE_EVENTS
  1046. X     DisposeEvents(dpy, (PointerMotionMask | EnterWindowMask |
  1047. X             LeaveWindowMask | ExposureMask));
  1048. X#endif
  1049. X     LockCursor(ItemWindow(current_item));
  1050. X     PlacePointer(current_menu,current_item); 
  1051. X     UnlockCursor();
  1052. X          
  1053. X     /* State Machine */
  1054. X     
  1055. X     while (CurrentState != Exit)
  1056. X     {
  1057. X      GetNextSignificantEvent(&Event_Reply, init_button);
  1058. X      switch (CurrentState)
  1059. X      {
  1060. X      case LevelControl:
  1061. X           CurrentState = LevelControlState(Event_Reply);
  1062. X           break;
  1063. X      case Initial:
  1064. X           CurrentState = InitialState(Event_Reply);
  1065. X           break;
  1066. X      case CheckTrigger:
  1067. X           CurrentState = CheckTriggerState(Event_Reply);
  1068. X           break;
  1069. X      case Leaf:
  1070. X           CurrentState = LeafState(Event_Reply, &selected);
  1071. X           break;
  1072. X      default:
  1073. X           Retch("(RTLmenu) YOW! Unknown State! (%d)\n",
  1074. X             CurrentState);
  1075. X           CurrentState = Exit;
  1076. X           break;
  1077. X      }
  1078. X     }
  1079. X     /* Clean up and exit */
  1080. X     
  1081. X     selected_item = (selected)? current_item : NULLITEM;
  1082. X     while (level)
  1083. X     {
  1084. X      if (selected)
  1085. X           SetInitialItem(current_menu, current_item);
  1086. X      PopSubmenu();
  1087. X     }
  1088. X     if (selected)
  1089. X     {
  1090. X      SetInitialItem(current_menu, current_item);
  1091. X     }
  1092. X     
  1093. X     Undisplay_Menu(current_menu);
  1094. X     UnlockCursor();
  1095. X     XUngrabPointer(dpy, CurrentTime);
  1096. X     
  1097. X     /* Throw out any left over events from menu world */
  1098. X     /*    if (TestOptionFlag(current_menu, savebits)) {
  1099. X       XSync(dpy,1); 
  1100. X       XUngrabServer(dpy, CurrentTime);  add this if grab added! 
  1101. X       }
  1102. X       else
  1103. X       XSync(dpy,0);*/
  1104. X     
  1105. X     /* Push back any events that were lying around when menus started */
  1106. X     
  1107. X     XFlush(dpy);
  1108. X#ifdef SAVE_EVENTS
  1109. X     DisposeEvents(dpy, (PointerMotionMask | EnterWindowMask |
  1110. X             LeaveWindowMask | ExposureMask));
  1111. X     RestoreEvents(dpy, &ev_save);
  1112. X#endif
  1113. X     Leave(selected_item)
  1114. X}
  1115. X
  1116. X/* Used for debugging */
  1117. X
  1118. Xvoid OutputEvent(Event_Reply)
  1119. XXEvent Event_Reply;
  1120. X{
  1121. X     Entry("OutputEvent")
  1122. X
  1123. X     switch (EventType(Event_Reply))
  1124. X     {
  1125. X     case ButtonPress:
  1126. X     case ButtonRelease:
  1127. X      DBUG_5("RTLmenu","Button Press/Release, button %d on window %d at time %d\n",
  1128. X         EventButton(Event_Reply), EventBWindow(Event_Reply), 
  1129. X         EventBTime(Event_Reply));
  1130. X      break;
  1131. X     case MotionNotify:
  1132. X      DBUG_5("RTLmenu","Motion Notify on window %d at time %d, x=%d\n", 
  1133. X         EventMWindow(Event_Reply), EventMTime(Event_Reply),
  1134. X         EventGetXCoord(Event_Reply));
  1135. X      break;
  1136. X     case EnterNotify:
  1137. X      DBUG_4("RTLmenu","Enter Notify on window %d at time %d\n",
  1138. X         EventXWindow(Event_Reply), EventXTime(Event_Reply));
  1139. X      break;
  1140. X     case LeaveNotify:
  1141. X      DBUG_4("RTLmenu","Leave Notify on window %d at time %d\n",
  1142. X         EventXWindow(Event_Reply), EventXTime(Event_Reply));
  1143. X      break;
  1144. X     default:
  1145. X      DBUG_3("RTLmenu","Unexpected event type %d\n", EventType(Event_Reply));
  1146. X      break;
  1147. X     }
  1148. X     Leave_void
  1149. X}
  1150. X
  1151. Xstatic Boolean locked = FALSE;
  1152. X
  1153. X/* Lock the cursor: make it disappear, and ignore events it generates.  */
  1154. X/* Optionally, confine it to a single window.                           */
  1155. X/* (Using "None" for confine_window doesn't confine it.    )            */
  1156. Xvoid LockCursor(confine_window)
  1157. XWindow confine_window;
  1158. X{
  1159. X     int result;
  1160. X     
  1161. X     Entry("LockCursor")
  1162. X     
  1163. X     locked = TRUE;
  1164. X     result = XGrabPointer(dpy,
  1165. X               RootWindow(dpy, MenuScreen(current_menu)),
  1166. X               True, lock_event_mask, GrabModeSync, 
  1167. X               GrabModeAsync, confine_window,
  1168. X               wait_cursor, CurrentTime);
  1169. X     DBUG_3("RTLmenu","Lock Cursor grab = %d\n",result);
  1170. X     Leave_void
  1171. X}
  1172. X
  1173. X/* Unlock (and unconfine) the cursor.  If cursor lock is not set,    */
  1174. X/* this does nothing.                                                */
  1175. X
  1176. Xvoid UnlockCursor()
  1177. X{
  1178. X     int result;
  1179. X     
  1180. X     Entry("UnlockCursor")
  1181. X     
  1182. X     if (locked)
  1183. X     {
  1184. X      locked = FALSE;
  1185. X      result = XGrabPointer(dpy, 
  1186. X                RootWindow(dpy, MenuScreen(current_menu)),
  1187. X                True,  unlock_event_mask,
  1188. X                GrabModeAsync, GrabModeAsync, None,
  1189. X                MenuCursor(current_menu), CurrentTime);
  1190. X      DBUG_3("RTLmenu","Unlock Cursor grab = %d\n",result);        
  1191. X     }
  1192. X     Leave_void
  1193. X}
  1194. X
  1195. X/* Keep getting the X events, until finding one that may be interesting */
  1196. X/* to the operation of the state machine. */
  1197. X
  1198. Xvoid GetNextSignificantEvent(Event_Reply,init_button)
  1199. XXEvent *Event_Reply;
  1200. Xint init_button;        /* the button that initiated the menu */
  1201. X{
  1202. X     XEvent Next_Event_Reply;
  1203. X     Boolean InsignificantEvent = True;
  1204. X     
  1205. X     Entry("GetNextSignificantEvent")
  1206. X     
  1207. X     /* Loop as long as any of a number of "insignificant" events */
  1208. X     /* are found; when the event no longer matches one of the tests, */
  1209. X     /* it is assumed to be "significant" and returned.*/
  1210. X     do
  1211. X     {
  1212. X      XNextEvent(dpy, Event_Reply);
  1213. X      DBUG_EXECUTE("RTLmenu", OutputEvent(*Event_Reply));
  1214. X      
  1215. X      /* If this event is an "enter", check whether there is a   */
  1216. X      /* "leave" for the same window already in the queue,       */
  1217. X      /* immediately following it; if so, throw them both out    */
  1218. X      /* and get the next event                                  */
  1219. X      /* NOTE: might try to look further ahead, but this is      */
  1220. X      /* tricky because other events might intervene.            */
  1221. X      
  1222. X      if ((EventType(*Event_Reply) == EnterNotify) &&
  1223. X          (EventXMode(*Event_Reply) == NotifyNormal) &&
  1224. X          (QLength(dpy) > 0) &&
  1225. X          (MenuGetMenu(current_menu, EventXWindow(*Event_Reply))
  1226. X           != current_menu))
  1227. X      {
  1228. X           XPeekEvent(dpy, &Next_Event_Reply);
  1229. X           if ((EventType(Next_Event_Reply) == LeaveNotify) &&
  1230. X           (EventXMode(Next_Event_Reply) == NotifyNormal) &&
  1231. X           (EventXWindow(Next_Event_Reply) == EventXWindow(*Event_Reply)))
  1232. X           {
  1233. X            DBUG_2("RTLmenu","TOSS: Enter/leave pair.\n");
  1234. X            XNextEvent(dpy, Event_Reply);
  1235. X            XNextEvent(dpy, Event_Reply);
  1236. X           }
  1237. X      }
  1238. X#ifdef SAVE_EVENTS
  1239. X      if (EventNotSignificant(*Event_Reply, init_button))
  1240. X      {
  1241. X           if (!(PointerEvent(*Event_Reply) || KeyEvent(*Event_Reply)
  1242. X             || EventType(*Event_Reply) == Expose))
  1243. X           {
  1244. X            /* might be significant elsewhere -- save it for later */
  1245. X            AddEventToStore(&ev_save, *Event_Reply);
  1246. X           }
  1247. X      }
  1248. X      else
  1249. X#else
  1250. X           if (!EventNotSignificant(*Event_Reply, init_button))
  1251. X#endif
  1252. X            InsignificantEvent = FALSE;
  1253. X     }
  1254. X     while (InsignificantEvent);
  1255. X     
  1256. X     DBUG_2("RTLmenu","--->");
  1257. X     Leave_void
  1258. X}
  1259. X
  1260. X/* Check whether the event matches one of the events considered */
  1261. X/* "not significant".*/
  1262. XBoolean EventNotSignificant(Event_Reply, init_button)
  1263. XXEvent Event_Reply;
  1264. Xint init_button;
  1265. X{
  1266. X     Entry("EventNotSignificant")
  1267. X
  1268. X     /* Insignificant if not in following list */
  1269. X     Leave(!((EventType(Event_Reply) == ButtonRelease) ||
  1270. X           (EventType(Event_Reply) == ButtonPress) ||
  1271. X           (EventType(Event_Reply) == MotionNotify) ||
  1272. X           (EventType(Event_Reply) == EnterNotify) ||
  1273. X           (EventType(Event_Reply) == Expose) ||
  1274. X           (EventType(Event_Reply) == LeaveNotify))
  1275. X         ||
  1276. X         /* Insignificant if leave or enter is not "Normal"  */
  1277. X         (((EventType(Event_Reply) == LeaveNotify) ||
  1278. X           (EventType(Event_Reply) == EnterNotify)) &&
  1279. X          (EventXMode(Event_Reply) != NotifyNormal))
  1280. X         ||
  1281. X         /* Insignificant if hit button other than initial one */
  1282. X         ((EventType(Event_Reply) == ButtonRelease) &&
  1283. X          (EventButton(Event_Reply) != init_button))
  1284. X         ||
  1285. X         /* Insignificant if tail end of a click -- and clicks allowed */
  1286. X         (click_allowed &&
  1287. X          (EventType(Event_Reply) == ButtonRelease) &&
  1288. X          (EventBTime(Event_Reply) - button_time < CLICK_TIME))
  1289. X         )
  1290. X}
  1291. X
  1292. XState LevelControlState(rep)
  1293. XXEvent rep;
  1294. X{
  1295. X     State next_state;
  1296. X     Menu *entered_menu;
  1297. X     MenuItem *entered_item;
  1298. X     
  1299. X     Entry("LevelControlState")
  1300. X     switch (EventType(rep))
  1301. X     {
  1302. X     case MotionNotify:
  1303. X     case LeaveNotify: 
  1304. X      next_state = LevelControl; /* loop back to this state */
  1305. X      break;
  1306. X     case EnterNotify:
  1307. X      /* Decide whether we've entered a menu window or item window */
  1308. X      entered_menu = MenuGetMenu(current_menu, EventXWindow(rep));
  1309. X      entered_item = MenuGetItem(current_menu,EventXWindow(rep));
  1310. X      
  1311. X      if ((MenuIsNull(entered_menu)) && (ItemIsNull(entered_item)))
  1312. X           /* Must be some other window; carry on */
  1313. X           next_state = LevelControl;
  1314. X      else if (!ItemIsNull(entered_item) &&
  1315. X           MenuIsDisplayed(ItemMenu(entered_item)))
  1316. X      {
  1317. X           /* we entered an item, but not a window. This should only happen */
  1318. X           /* when we stayed in the parent of the current submenu.  So,     */
  1319. X           /* Pop that submenu and get to the item.                         */
  1320. X           if (level)
  1321. X           {
  1322. X            LockCursor(ItemWindow(entered_item));
  1323. X            PopSubmenu();
  1324. X            ProcessExposeEvents();
  1325. X            UnlockCursor();
  1326. X            current_item = entered_item;
  1327. X            Highlight(current_item);
  1328. X            next_state = GetItemState(rep);
  1329. X           }
  1330. X           else
  1331. X           { 
  1332. X            Retch("(RTLmenu) Tried to pop the root menu...\n");
  1333. X            next_state = Exit;
  1334. X           }
  1335. X      }
  1336. X      
  1337. X      else if (!MenuIsNull(entered_menu)&&
  1338. X           MenuIsDisplayed(entered_menu))
  1339. X      {
  1340. X           /* entered a menu that is displayed */
  1341. X           while ((current_menu != entered_menu) && level)
  1342. X            /* drop down the menu that was entered */
  1343. X            PopSubmenu();
  1344. X           ProcessExposeEvents();
  1345. X           UnlockCursor();
  1346. X           if (current_menu == entered_menu)
  1347. X            next_state = Initial;
  1348. X           else
  1349. X           {
  1350. X            next_state = Exit;
  1351. X            Retch("(RTLmenu) Couldn't find the menu I entered!!\n");
  1352. X           }
  1353. X      }
  1354. X      else 
  1355. X           next_state = LevelControl;
  1356. X      break;
  1357. X     case ButtonRelease:
  1358. X      next_state = Exit;
  1359. X      break;
  1360. X     default:
  1361. X      Retch("RTLmenu","YOW! Unexpected event! (%d)\n", rep.type);
  1362. X      next_state = Exit;
  1363. X      break;
  1364. X     }
  1365. X     Leave(next_state)
  1366. X}
  1367. X
  1368. X/* Figure out the status of the item we've just entered */
  1369. XState GetItemState(rep)
  1370. XXEvent rep;
  1371. X{
  1372. X     int open_x;
  1373. X     State next_state;
  1374. X     
  1375. X     Entry("GetItemState")
  1376. X     if (ItemIsNull(current_item))
  1377. X     {
  1378. X      Retch("(RTLmenu) null current item!");
  1379. X      next_state = Exit;
  1380. X     }
  1381. X     else if (MenuIsNull(current_menu))
  1382. X     {
  1383. X      Retch("(RTLmenu) null current menu!");
  1384. X      next_state = Exit;
  1385. X     }
  1386. X     else if (ItemIsLeaf(current_item))
  1387. X     {
  1388. X      if (MenuHasInitialItem(current_menu))
  1389. X           ClearInitialItem(current_menu);
  1390. X      next_state = Leaf;
  1391. X     }
  1392. X     else if (EventGetXCoord(rep) >= (int)(ItemGetArrowPosition(current_item) - 4))
  1393. X     {
  1394. X      /* entered item in "auto pop-up zone", i.e., over pull-right arrow. */
  1395. X      LockCursor(ItemWindow(current_item));
  1396. X      TossExtraMoves(ItemWindow(current_item));
  1397. X      if (PushSubmenu(EventXRootX(rep)))
  1398. X      {
  1399. X           LockCursor(ItemWindow(current_item));
  1400. X           PlacePointer(current_menu, current_item); 
  1401. X           next_state = Initial;
  1402. X           ProcessExposeEvents();
  1403. X      }
  1404. X      else
  1405. X           next_state = CheckTrigger;
  1406. X      UnlockCursor();
  1407. X     }
  1408. X     else if (MenuHasInitialItem(current_menu))
  1409. X     {
  1410. X      /* Entered menu has initial item -- move to it */
  1411. X      DBUG_2("RTLmenu","Pushing for initial item.");
  1412. X      current_item = GetInitialItem(current_menu);
  1413. X      open_x = ItemGetArrowPosition(current_item) +
  1414. X           EventXRootX(rep);        
  1415. X      ClearInitialItem(current_menu);
  1416. X      LockCursor(ItemWindow(current_item));
  1417. X      if (PushSubmenu(open_x))
  1418. X      {
  1419. X           ProcessExposeEvents();
  1420. X           LockCursor(ItemWindow(current_item));
  1421. X           PlacePointer(current_menu, current_item); 
  1422. X           next_state = Initial;
  1423. X      }
  1424. X      UnlockCursor();
  1425. X     }
  1426. X     else /* parent pull */
  1427. X      next_state = CheckTrigger;
  1428. X     Leave(next_state)
  1429. X}
  1430. X
  1431. XState InitialState( rep)
  1432. XXEvent rep;
  1433. X{
  1434. X     State next_state;
  1435. X     
  1436. X     Entry("Initial")
  1437. X     switch (EventType(rep))
  1438. X     {
  1439. X     case EnterNotify:
  1440. X      if (MenuIsNull(current_menu))
  1441. X      {
  1442. X           Retch("(RTLmenu) null current menu!?!?");
  1443. X           next_state = Exit;
  1444. X      }
  1445. X      else if (EventXDetail(rep) == NotifyInferior)
  1446. X           next_state = Initial;
  1447. X      else
  1448. X      {
  1449. X           current_item = MenuGetItem(current_menu, EventXWindow(rep));
  1450. X           if (ItemIsNull(current_item))
  1451. X           {
  1452. X            /* Retch("(RTLmenu) Window entered not an item!\n"); */
  1453. X            next_state = Initial;
  1454. X           }
  1455. X           else
  1456. X           {
  1457. X            Highlight(current_item);
  1458. X            next_state = GetItemState(rep);
  1459. X           }
  1460. X      }
  1461. X      break;
  1462. X     case LeaveNotify:
  1463. X      /* Decide whether we're actually leaving      */
  1464. X      /* this menu for another submenu or the root, */
  1465. X      /* or going into an item.                     */
  1466. X      next_state = (EventXDetail(rep) == NotifyInferior)?
  1467. X           Initial : LevelControl;
  1468. X      break;
  1469. X     case ButtonRelease:
  1470. X      next_state = Exit;
  1471. X      break;
  1472. X     case MotionNotify:
  1473. X      next_state = Initial;
  1474. X      break;
  1475. X     default:
  1476. X      Retch("(RTLmenu) YOW! Unexpected event! (%d)\n", rep.type);
  1477. X      next_state = Exit;
  1478. X      break;
  1479. X     }
  1480. X     Leave(next_state)
  1481. X}
  1482. X
  1483. X#define NotSet -1
  1484. X/* Look to see if pull-right is requested */
  1485. XState CheckTriggerState(rep)
  1486. XXEvent rep;
  1487. X{
  1488. X     State next_state = CheckTrigger;
  1489. X     static int Trigger = NotSet;
  1490. X     static int OldX, NewX, childX, button;
  1491. X     
  1492. X     Entry("CheckTrigger")
  1493. X     if (MenuIsNull(current_menu) || ItemIsNull(current_item))
  1494. X     {
  1495. X      Retch("(RTLmenu) Null menu or item...");
  1496. X      next_state = Exit;
  1497. X      goto exit;
  1498. X     }
  1499. X     if (Trigger == NotSet) /* set it */
  1500. X     {
  1501. X      Trigger = MIN(EventGetXCoord(rep) + MenuDelta(current_menu),
  1502. X            ItemGetArrowPosition(current_item));
  1503. X      NewX = NotSet;
  1504. X     }
  1505. X     switch (EventType(rep))
  1506. X     {
  1507. X     case LeaveNotify:
  1508. X      next_state = Initial;
  1509. X      Unhighlight(MenuGetItem(current_menu, EventXWindow(rep)));
  1510. X      Trigger = NotSet;
  1511. X      break;
  1512. X     case ButtonRelease:
  1513. X      next_state = Exit;
  1514. X      Trigger = NotSet;
  1515. X      break;
  1516. X      
  1517. X     case ButtonPress:
  1518. X      button = rep.xbutton.button;
  1519. X      while (TRUE) {
  1520. X           XNextEvent(dpy, &rep);
  1521. X           if (rep.type == ButtonRelease &&
  1522. X           rep.xbutton.button == button)
  1523. X            break;
  1524. X      }
  1525. X      next_state = CheckTrigger;
  1526. X      childX = TestOptionFlag(current_menu, fixedchild) ?
  1527. X           (MenuX(current_menu) + ItemGetArrowPosition(current_item)) :
  1528. X            EventXRootX(rep);
  1529. X      Trigger = NotSet;
  1530. X      if (PushSubmenu(childX))
  1531. X      {
  1532. X           next_state = LevelControl;
  1533. X           ProcessExposeEvents();
  1534. X           LockCursor(ItemWindow(current_item));
  1535. X           PlacePointer(current_menu, current_item);
  1536. X      }
  1537. X      UnlockCursor();
  1538. X      break;
  1539. X
  1540. X     case MotionNotify:
  1541. X      next_state = CheckTrigger;
  1542. X      OldX = NewX;
  1543. X      NewX = EventGetXCoord(rep);
  1544. X      if (NewX >= Trigger)
  1545. X      {
  1546. X           LockCursor(ItemWindow(current_item));
  1547. X           childX = TestOptionFlag(current_menu, fixedchild)?
  1548. X            (MenuX(current_menu) + ItemGetArrowPosition(current_item)):
  1549. X             EventXRootX(rep);
  1550. X           Trigger = NotSet;
  1551. X           if (PushSubmenu(childX))
  1552. X           {
  1553. X            next_state = LevelControl;
  1554. X            ProcessExposeEvents();
  1555. X            LockCursor(ItemWindow(current_item));
  1556. X            PlacePointer(current_menu, current_item); 
  1557. X           }
  1558. X           UnlockCursor();
  1559. X      }
  1560. X      else if (NewX < OldX) /* reverse motion */
  1561. X           Trigger = MIN(Trigger, NewX + MenuDelta(current_menu));
  1562. X      break;
  1563. X
  1564. X     default:
  1565. X      Retch("(RTLmenu) YOW! Unexpected event!\n");
  1566. X      next_state = Exit;
  1567. X      break;
  1568. X     }
  1569. X exit:
  1570. X     Leave(next_state)
  1571. X}
  1572. X
  1573. XState LeafState(rep,selected)
  1574. XXEvent rep;
  1575. XBoolean *selected;
  1576. X{
  1577. X     State next_state;
  1578. X     
  1579. X     Entry("LeafState")
  1580. X     switch(EventType(rep))
  1581. X     {
  1582. X     case LeaveNotify:
  1583. X      Unhighlight(MenuGetItem(current_menu, EventXWindow(rep)));
  1584. X      next_state = Initial;
  1585. X      break;
  1586. X      
  1587. X     case ButtonRelease:
  1588. X      *selected = TRUE;
  1589. X      next_state = Exit;
  1590. X      break;
  1591. X     
  1592. X     case ButtonPress:
  1593. X     case EnterNotify:
  1594. X     case MotionNotify: /* if events set right, this never happens */
  1595. X      next_state = Leaf;
  1596. X      break;
  1597. X      
  1598. X     default:
  1599. X      Retch("(RTLMenu) YOW! Unexpected event! (%d)\n",
  1600. X        rep.type);
  1601. X      next_state = Exit;
  1602. X      break;
  1603. X     }
  1604. X     Leave(next_state)
  1605. X}
  1606. X
  1607. XBoolean PushSubmenu(x)
  1608. Xint x;
  1609. X{
  1610. X     int y;
  1611. X     Boolean pushed;
  1612. X     MenuItem *new_current_item;
  1613. X     
  1614. X     Entry("PushSubmenu")
  1615. X
  1616. X     if (ItemIsNull(current_item))
  1617. X     {
  1618. X      Retch("(RTLMenu) Can't push from null item.\n");
  1619. X      pushed = FALSE;
  1620. X     }
  1621. X     else if (MenuIsNull(ItemSubmenu(current_item)))
  1622. X     {
  1623. X      Retch("(RTLmenu) Null submenu.\n");
  1624. X      pushed = FALSE;
  1625. X     }    
  1626. X     else if (ItemIsNull(MenuItems(ItemSubmenu(current_item))))
  1627. X      /* submenu has no items -- don't push, but not an error */
  1628. X      pushed = FALSE;
  1629. X     else
  1630. X     {
  1631. X      y =  ItemGetMiddleY(current_item);
  1632. X      ++level;
  1633. X      
  1634. X      if (new_current_item =
  1635. X          Display_Menu(ItemSubmenu(current_item), current_menu, x, y))
  1636. X      {
  1637. X           XFlush(dpy);
  1638. X           current_menu = ItemSubmenu(current_item);
  1639. X           current_item = new_current_item;
  1640. X           if (ItemIsDeaf(current_item) && Autoselect)
  1641. X            current_item = current_item->nextItem;
  1642. X           pushed = TRUE;
  1643. X      }
  1644. X      else
  1645. X      {
  1646. X           Retch("(RTLmenu) Display_Menu failed!\n");
  1647. X           pushed = FALSE;
  1648. X      }
  1649. X     }
  1650. X     Leave(pushed)
  1651. X}
  1652. X
  1653. Xvoid PopSubmenu()
  1654. X{
  1655. X     Menu *parent;
  1656. X     MenuItem *item;
  1657. X     
  1658. X     Entry("PopSubmenu")
  1659. X     --level;
  1660. X     parent = current_menu->parentMenu;
  1661. X     Undisplay_Menu(current_menu);
  1662. X     current_menu = parent;
  1663. X     if (!MenuIsNull(current_menu))
  1664. X     {
  1665. X      item = MenuItemHighlighted(current_menu);
  1666. X      if (!ItemIsNull(item))
  1667. X      {
  1668. X           current_item = item;
  1669. X      }
  1670. X     }
  1671. X     
  1672. X     Leave_void
  1673. X}
  1674. X
  1675. Xvoid Highlight(item)
  1676. XMenuItem *item;
  1677. X{
  1678. X     MenuItem *old_highlight;
  1679. X     
  1680. X     Entry("Highlight")
  1681. X     
  1682. X     old_highlight = MenuItemHighlighted(current_menu);
  1683. X     if ((item != old_highlight) && /* else, already highlighted */
  1684. X     (!ItemIsNull(item)))
  1685. X     {
  1686. X      if (!ItemIsNull(old_highlight) && !ItemIsDeaf(item))
  1687. X           Unhighlight(old_highlight); 
  1688. X      SetHighlightItem(ItemMenu(item), item);
  1689. X      Draw_Item(ItemMenu(item), item);
  1690. X     }
  1691. X     Leave_void
  1692. X}
  1693. X
  1694. Xvoid Unhighlight(item)
  1695. XMenuItem *item;
  1696. X{
  1697. X     Entry("Unhighlight")
  1698. X     if (!ItemIsNull(item))
  1699. X     {
  1700. X      if (MenuItemHighlighted(current_menu) == item)
  1701. X      {
  1702. X           ResetHighlightItem(ItemMenu(item));
  1703. X           Draw_Item(ItemMenu(item), item);
  1704. X      }
  1705. X     }
  1706. X     Leave_void
  1707. X}
  1708. X
  1709. Xvoid TossExtraMoves(window)
  1710. XWindow window;
  1711. X{
  1712. X     XEvent ev;
  1713. X     
  1714. X     Entry("TossExtraMoves")
  1715. X     while (XCheckTypedWindowEvent(dpy, window, MotionNotify, &ev))
  1716. X      DBUG_2("RTLmenu","Tossing extra motion.\n");
  1717. X     Leave_void
  1718. X}
  1719. X
  1720. X
  1721. Xvoid ProcessExposeEvents()
  1722. X{
  1723. X     MenuItem *item;
  1724. X     XEvent ev;
  1725. X     
  1726. X     Entry("ProcessExposeEvents")
  1727. X
  1728. X     XSync(dpy,0);
  1729. X     while (XCheckTypedEvent(dpy, Expose, &ev))
  1730. X     {
  1731. X      item = MenuGetItem(current_menu, EventXWindow(ev));
  1732. X      if (!ItemIsNull(item))
  1733. X           Draw_Item(ItemMenu(item), item);
  1734. X     }
  1735. X     Leave_void
  1736. X}
  1737. END_OF_FILE
  1738. if test 26567 -ne `wc -c <'menus/track_menu.c'`; then
  1739.     echo shar: \"'menus/track_menu.c'\" unpacked with wrong size!
  1740. fi
  1741. # end of 'menus/track_menu.c'
  1742. fi
  1743. echo shar: End of archive 5 \(of 12\).
  1744. cp /dev/null ark5isdone
  1745. MISSING=""
  1746. for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
  1747.     if test ! -f ark${I}isdone ; then
  1748.     MISSING="${MISSING} ${I}"
  1749.     fi
  1750. done
  1751. if test "${MISSING}" = "" ; then
  1752.     echo You have unpacked all 12 archives.
  1753.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1754. else
  1755.     echo You still need to unpack the following archives:
  1756.     echo "        " ${MISSING}
  1757. fi
  1758. ##  End of shell archive.
  1759. exit 0
  1760. -- 
  1761. Mike Wexler(wyse!mikew)    Phone: (408)433-1000 x1330
  1762. Moderator of comp.sources.x
  1763.